home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 364_01 / parse_ca.c < prev    next >
C/C++ Source or Header  |  1992-05-24  |  12KB  |  465 lines

  1. /*
  2. HEADER:         ;
  3. TITLE:          C-ACROSS;
  4. VERSION         1.02
  5.  
  6. DESCRIPTION:   "Utility for multiple module programs. Produces
  7.       Six indexes of functions, prototypes, and globals that
  8.       enable user to 'see across' modules for use in checking
  9.       and comparison.  One of these is type of hierarchical
  10.       functions list, a listing by module of functions
  11.       and calls made FROM them; another is alphabetical list
  12.       of functions and calls made TO them. Globals listed
  13.       in schematic descriptors which record all modifiers
  14.       and qualifiers and enable checking of declarators
  15.       across modules. Creates, on request, header file
  16.       consisting of prototypes constructed from function
  17.       definitions. Can list user types #defined and some
  18.       preprocessor #defines. Full documentation in README.CA";
  19.  
  20. KEYWORDS:       Utility, Cross Reference, Deubgging;
  21. SYSTEM:         MS-DOS;
  22. FILENAME:       PARSE_CA.C;
  23.  
  24. WARNINGS:      "1. Assumes function definitions conform with
  25.         ANSI standards and have prototype form. See
  26.         also "Caveats and Restrictions" in README.CA.
  27.         2. Assumes syntactically correct source files.
  28.         3. Written and tested using Microsoft QuickC.
  29.         4. Copyright retained.  See Copyright
  30.         information in README.CA.";
  31.  
  32. SEE-ALSO:      EXIT_CA.C, FUNC_CA.C, GLOB_CA.C, IFDEF_CA.C, INTF_CA.C,
  33.            LINKL_CA.C, TDEF_CA.C, TYPES_CA, UTIL_CA.C,
  34.            UTLG_CA.C, XRF_CA.C, README.CA,
  35.            CA.H, CA.PRJ, CA.RPT, CDECL_CA.H, KEYWORDS.H;
  36. AUTHORS:       Myron Turner;
  37. COMPILERS:     Microsoft C;
  38.  
  39. */
  40. /***************************  C-ACROSS  ***************************
  41.                    V. 1.02
  42.                Copyright (C) Myron Turner
  43.  
  44.               333 Bartlet Ave.
  45.               Winnipeg, Manitoba
  46.               Canada R3L 0Z9
  47.               (204) 284-8387
  48.  
  49. *********************************************************************/
  50.  
  51.  
  52. #include <stdio.h>
  53. #include <stdlib.h>
  54. #include <string.h>
  55. #include <ctype.h>
  56. #include <malloc.h>
  57. #include "ca.h"
  58. #include "ca_decl.h"
  59. #define EXTERNAL
  60. #include "keywords.h"
  61.  
  62. /* externs and globals */
  63. char *prog_line;
  64. char token[81];
  65. extern char **bsearch_start;
  66. extern int function_no;
  67. static int fnp_assignment;
  68. extern struct func *calling_function;
  69.  
  70. extern size_t GLfpSsize;
  71. struct GLoc_fnptr_stack
  72. {
  73.    char fnptr[32];
  74.    char fn_name[32];
  75.    char *caller;
  76. } *GLfptrstack;
  77. size_t GLfptrstack_Ptr = 0;
  78. static int ini_GLstack(void);
  79. static struct GLoc_fnptr_stack pop_fn_name(char *token);
  80.  
  81. static void process_calls_from( struct func *function, FILE *rpt,
  82.                     char *token, int current_line);
  83. /******BEGIN ROUTINES*********/
  84. #define DEBUG_LINE 38
  85. void parse(FILE *fp, FILE *rpt, unsigned end_func, unsigned next_function,
  86.                             unsigned *current_line)
  87. {
  88.   char buffer[261];
  89.   int token_type = NO_TOKEN;
  90.   char *func_name;
  91.  
  92.   fnp_assignment = 0;
  93.   memset( buffer, '\0', 261 );
  94.   if (next_function == LAST_FUNCTION) end_func = LAST_FUNCTION;
  95.   /* reads from file all lines up to first line of next fuction */
  96.   /* next_function = first line of next function */
  97.   while (  (fgets (buffer, 160, fp))   && *current_line < next_function )
  98.     {
  99.      prog_line = buffer;
  100.  
  101.      (*current_line)++;
  102.      if (*current_line == DEBUG_LINE)
  103.         *current_line = DEBUG_LINE;
  104.      while (*prog_line)
  105.       {
  106.       if (*prog_line == '\n') break;
  107.       if(  (token_type = get_token()) ) {
  108.     int element;
  109.  
  110.       element = ( binary_search( bsearch_start, function_no, token) );
  111.  
  112.       if (element > - 1 && *current_line < end_func) {
  113.         if (token_type == IS_TOKEN) {
  114.           process_calls_from((struct func *) *(bsearch_start + element),
  115.                       rpt, token, *current_line);
  116.         }
  117.         else if (token_type == PTR_ASSIGNED)
  118.           if (push_fnptr(prog_line, buffer, token))
  119.          GLfptrstack[GLfptrstack_Ptr - 1].caller
  120.                      = calling_function->name;
  121.       }
  122.  
  123.       /* if a function ptr has been assigned and not identified in the */
  124.       /* preceding search, it must be a local ptr:  pop the function   */
  125.       /* to which it points and process it:
  126.       */
  127.       else if (fnp_assignment)
  128.        if (token_type == IS_TOKEN && *current_line < end_func) {
  129.         if ( (func_name = (pop_fn_name(token)).fn_name) != NULL) {
  130.          element = (binary_search(bsearch_start, function_no, func_name));
  131.          if (element > - 1)
  132.            process_calls_from((struct func *) *(bsearch_start + element),
  133.                        rpt, func_name, *current_line);
  134.            }
  135.          }
  136.  
  137.     }
  138.  
  139.       }
  140.    }
  141.    (*current_line)++;
  142.  
  143. }
  144.  
  145.  
  146. int get_token(void)
  147. {
  148.  char *temp;
  149.  int __type;
  150.  
  151.   temp = token;
  152.  
  153.   while ( iswhite(*prog_line)) {
  154.     if (*prog_line == '\n' || !*prog_line) return (NO_TOKEN);
  155.     prog_line++;
  156.                    }
  157.  
  158.   while ( isliteral(prog_line)) {
  159.     if (*prog_line == '\n' || !*prog_line) return (NO_TOKEN);
  160.     prog_line++;            }
  161.   while (iswhite(*prog_line)) prog_line++;
  162.  
  163.   if ( isalpha( (int) *prog_line ) || *prog_line == '_')   {
  164.      while ( !isdelim(*prog_line) ) {
  165.        if (*prog_line == '\n' || !*prog_line) return (NO_TOKEN);
  166.        *temp++ = *prog_line++;
  167.                     }
  168.      while ( iswhite(*prog_line) )
  169.      {
  170.      if (*prog_line == '\n' || !*prog_line) return (NO_TOKEN);
  171.       prog_line++;
  172.      }
  173.      if (*prog_line == '(' || *prog_line == ';')
  174.        {
  175.        *temp = '\0';
  176.        if (*prog_line == ';') return (PTR_ASSIGNED);
  177.        return (IS_TOKEN);
  178.        }
  179.        else {
  180.        *temp = '\0';
  181.        return (NO_TOKEN);
  182.        }
  183.  
  184.                     }
  185.       else if (*prog_line) prog_line++;   /* not alpha, so move one byte */
  186.                       /* forward and return */
  187.  return (0);
  188.  
  189. }
  190.  
  191. /* buffer holds the entire current line: p points to end of expression */
  192. int push_fnptr(char *p, char *buffer, char *func_name)
  193. {
  194.   char token[32], *end_token = NULL, *equal_sign;
  195.   char *function_name = NULL;
  196.   size_t strL = 0;
  197.   static ini = 0;
  198.   int strpos, __type, GL_decl = 0;
  199.   extern FILE *scrn_out;
  200.  
  201.    if (!ini)
  202.       if ( !(ini = ini_GLstack()) ) return(0);
  203.    if (GLfptrstack_Ptr >= GLfpSsize) {
  204.      if (scrn_out != (FILE *)stdout) fprintf(scrn_out,
  205.       "Function Pointer Stack at Limit: %d\n", GLfpSsize);
  206.      printf("Function Pointer Stack at Limit: %d\n\a", GLfpSsize);
  207.      return(0);
  208.      }
  209.  
  210.    if (strpos = data_type_ (buffer, &__type)) {
  211.       char *ptr;
  212.       buffer += strpos;
  213.       while (*buffer != '(' && *buffer) buffer++;
  214.       if(*buffer) {
  215.     while (! (isalnum(*buffer) || *buffer == '_') ) buffer++;
  216.     ptr = buffer;
  217.     while ( isalnum(*ptr) || *ptr == '_') {
  218.        ptr++;
  219.        strL++;
  220.        }
  221.     if(strL > 31) strL = 31;
  222.     strncpy(token, buffer, strL);
  223.     token[strL] = '\0';
  224.     GL_decl = 1;
  225.     }
  226.       }
  227.  
  228.    while (p > buffer) {
  229.    if ( *p == '=') {
  230.  
  231.       equal_sign = p;    /* save place */
  232.  
  233.       if (!GL_decl) {
  234.     p--;
  235.     while (isspace(*p)) p--;
  236.     end_token = p;
  237.     while ( isalnum(*p) || *p == '_') p--;
  238.     p++;
  239.     if (p < buffer) p = buffer;     /* precautionary */
  240.     strL = (end_token - p) + 1;
  241.     if(strL > 31) strL = 31;
  242.     strncpy(token, p, strL);
  243.     token[strL] = '\0';
  244.     }
  245.       strcpy(GLfptrstack[GLfptrstack_Ptr].fnptr , token);
  246.  
  247.       equal_sign++;
  248.       while (isspace(*equal_sign)) equal_sign++;
  249.       strL = 0;
  250.       function_name = token;
  251.       strcpy(function_name, equal_sign);
  252.  
  253.       while ( (++strL < 32)  &&
  254.           (isalnum(*function_name) || *function_name == '_') )
  255.                        function_name++;
  256.       *function_name = '\0';
  257.       strcpy(GLfptrstack[GLfptrstack_Ptr].fn_name , token);
  258.       GLfptrstack_Ptr++;
  259.       fnp_assignment = 1;
  260.       break;
  261.       }
  262.    p--;
  263.    }
  264.  
  265.    return(1);
  266. }
  267.  
  268. /*  pops name of function associated with function pointer */
  269. static struct GLoc_fnptr_stack pop_fn_name(char *token)
  270. {
  271.   size_t i, element = - 1;
  272.   struct GLoc_fnptr_stack temp = { "NULL", "NULL", '\0' } ;
  273.  
  274.   for (i = 0; i <  GLfptrstack_Ptr; i++)
  275.       if ( !(strcmp(GLfptrstack[i].fnptr, token )) )
  276.           element = i;
  277.  
  278.       if (element != -1) return(GLfptrstack[element]);
  279.       return (temp);
  280. }
  281.  
  282.  
  283. int iswhite(char c)
  284. {
  285.  if (c == ' ' || c == '\x9') return (1);
  286.  return(0);
  287. }
  288.  
  289. int isliteral(char *pgmline)
  290. {
  291. static int String = 0;
  292. static int Comment = 0;
  293.  
  294. if (!Comment)
  295. if (*pgmline == '\"' && *(pgmline - 1) != '\\'